#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#include "tcp_ringbuffer.h"

static inline __attribute__((const))
int is_power_of_2(unsigned long n)
{
	return (n != 0 && ((n & (n - 1)) == 0));
}

static unsigned long roundup_power_of_two(unsigned long n)
{
    if((n & (n-1)) == 0)
        return n;
    
    unsigned long maxulong = (unsigned long)((unsigned long)~0);
    unsigned long andv = ~(maxulong&(maxulong>>1));

    while((andv & n) == 0)
        andv = andv>>1;

    return andv<<1;
}

//创建ringbuffer 
ringbuffer_t * ringbuffer_create(unsigned int size)
{
	//对入参进行校验 并且是2的次方
	if (!is_power_of_2(size)) {
        size = roundup_power_of_two(size);
	}

	ringbuffer_t * ring_buffer;
	ring_buffer = (ringbuffer_t*)malloc(sizeof(*ring_buffer));
	if(ring_buffer == NULL)
	{
		printf("create ringbuffer error \n");
		return NULL;
	}

	ring_buffer->data = (void*)malloc(size);
	if(ring_buffer->data == NULL)
	{
		printf("create ringbuffer data error \n");
		free(ring_buffer);
		return NULL;
	}

	ring_buffer->size = size;
	ring_buffer->read_pos = 0;
	ring_buffer->write_pos = 0;
	return ring_buffer;
}

//销毁ringbuffer
void ringbuffer_destroy(ringbuffer_t * ring_buffer)
{
	if(ring_buffer)
	{
		if(ring_buffer->data)
		{
			free(ring_buffer->data);
			ring_buffer->data = NULL;
		}
		free(ring_buffer);
		ring_buffer = NULL;
	}
}


// typedef struct RINGBUFF_T{
// 	void * data;
// 	unsigned int size;
// 	unsigned int read_pos;   //数据起始位置
// 	unsigned int write_pos;  //数据终止位置
// }ringbuffer_t;


//往ringbuffer中存数据 写入
int ringbuffer_put(ringbuffer_t * ring_buffer, const char* buffer, unsigned int len)
{
	if(ring_buffer->write_pos >=ring_buffer->read_pos &&(len <(ring_buffer->size - ring_buffer->write_pos +ring_buffer->read_pos)))
	{
		//进行拷贝
		if(ring_buffer->size - ring_buffer->write_pos >len)
		{
			memcpy(ring_buffer->data + ring_buffer->write_pos, buffer, len);
			ring_buffer->write_pos += len;
		}else
		{
			unsigned int right_space_len = ring_buffer->size - ring_buffer->write_pos;
			memcpy(ring_buffer->data + ring_buffer->write_pos, buffer, right_space_len);
			memcpy(ring_buffer->data, buffer+right_space_len, len - right_space_len);
			ring_buffer->write_pos = len - right_space_len;
		}
		return 0;
	}

	if(ring_buffer->write_pos <ring_buffer->read_pos && (ring_buffer->read_pos - ring_buffer->write_pos) >len)
	{
		memcpy(ring_buffer->data + ring_buffer->write_pos, buffer, len);
		ring_buffer->write_pos += len;
		return 0;
	}

	return -1;
}

//判断是否是完整的数据  然后进行处理
int ringbuffer_get_len(ringbuffer_t *ring_buffer)
{
	//对ringbuffer中的数据做判断解析  如果是完整的数据  则提取出去
	if(ringbuffer_use_len(ring_buffer) < strlen("FFFF0D0A<header><tail>0D0AFEFE"))
	{
		printf("ringbuffer data is error [%d], [%ld]\n", ringbuffer_use_len(ring_buffer),  strlen("FFFF0D0A<header><tail>0D0AFEFE"));
		return -1;
	}
	//判断是否是终结的字段
	const char* end_str = "<tail>0D0AFEFE";
	char check_end_str[20] = {0};
	if(ring_buffer->write_pos >strlen(end_str))
	{
		memcpy(check_end_str, ring_buffer->data+ring_buffer->write_pos - (strlen(end_str)),  strlen(end_str));
	}else
	{
		unsigned int left_len = ring_buffer->write_pos;
		memcpy(check_end_str, ring_buffer->data +ring_buffer->size - (strlen(end_str) - left_len), ring_buffer->size - (strlen(end_str) - left_len));
		memcpy(check_end_str + (strlen(end_str) - left_len), ring_buffer->data, left_len);
	}
	printf("get check_end_str is %s \n", check_end_str);


	char * ret_addr = strstr(check_end_str, end_str);
	if(ret_addr == NULL)
	{
		return -1;
	}

	if(check_end_str - ret_addr != 0)
	{
		printf("DDDDD :why end string is error");
		return -1;
	}

	return ringbuffer_use_len(ring_buffer);
}

//从ringbuffer中取数据做处理, 判断接收到的字符是否是终结符号，就可以去做处理
//取完数据后重置ringbuffer的位置  读取
int ringbuffer_get(ringbuffer_t * ring_buffer, char * buffer, unsigned int len)
{
	//这里建立在ringbuffer_get_len 的基础上，传入入参，取出数据
	int data_len = ringbuffer_use_len(ring_buffer);
	if(data_len >= len)
	{
		printf("para buffer is not enough space \n");
		return -1;
	}

	if(ring_buffer->write_pos >ring_buffer->read_pos )
	{
		printf("get data from ringbuffer len: [%d] \n", ring_buffer->write_pos - ring_buffer->read_pos);
		memcpy(buffer, ring_buffer->data + ring_buffer->read_pos, data_len);
	}else
	{
		memcpy(buffer, ring_buffer->data+ring_buffer->read_pos, ring_buffer->size - ring_buffer->read_pos);
		memcpy(buffer+ring_buffer->size - ring_buffer->read_pos, ring_buffer->data, data_len - (ring_buffer->size - ring_buffer->read_pos));
	}

	ring_buffer->write_pos = 0;
	ring_buffer->read_pos = 0;
	return 0;
}

//直接从socket中读数据放入ringbuffer中也可以
int ringbuffer_get_from_dev()
{
	return 0;
}
//直接从ringbuffer中取数据用socket进行发送
int ringbuffer_put_to_dev()
{
	return 0;
}

void ringbuffer_reset(ringbuffer_t * ring_buffer)
{
	ring_buffer->read_pos = ring_buffer->write_pos = 0;
}

int ringbuffer_use_len(ringbuffer_t * ring_buffer)
{
	if(ring_buffer->write_pos >= ring_buffer->read_pos)
	{
		return ring_buffer->write_pos-ring_buffer->read_pos;
	}

	return ring_buffer->write_pos + ring_buffer->size - ring_buffer->read_pos;
}

int ringbuffer_space_len(ringbuffer_t * ring_buffer)
{
	if(ring_buffer->write_pos >= ring_buffer->read_pos)
	{
		return ring_buffer->read_pos +(ring_buffer->size - ring_buffer->write_pos);
	}

	return ring_buffer->read_pos - ring_buffer->write_pos;
}

int ringbuffer_isempty(ringbuffer_t * ring_buffer)
{
	return ringbuffer_use_len(ring_buffer) == 0? 0 :-1;
}

int ringbuffer_isfull(ringbuffer_t * ring_buffer)
{
	return ringbuffer_space_len(ring_buffer) == 0? 0 :-1;
}

// int get_ringbuffer_size(ringbuffer_t * ring_buffer)
// {
// 	return ring_buffer->size;
// }